home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / m68k / cc68k.arc / GENCODE.C < prev    next >
C/C++ Source or Header  |  1986-10-26  |  39KB  |  1,084 lines

  1. #include        "stdio.h"
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or question
  18. s
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. /*
  27.  *      this module contains all of the code generation routines
  28.  *      for evaluating expressions and conditions.
  29.  */
  30.  
  31. extern struct amode     push[], pop[];
  32.  
  33. struct amode    *gen_expr();            /* forward declaration */
  34.  
  35. struct amode    *make_label(lab)
  36. /*
  37.  *      construct a reference node for an internal label number.
  38.  */
  39. int     lab;
  40. {       struct enode    *lnode;
  41.         struct amode    *ap;
  42.         lnode =(struct enode *)xalloc(sizeof(struct enode));
  43.         lnode->nodetype = en_labcon;
  44.         lnode->v.i = lab;
  45.         ap =(struct amode *)xalloc(sizeof(struct amode));
  46.         ap->mode = am_direct;
  47.         ap->offset = lnode;
  48.         return ap;
  49. }
  50.  
  51. struct amode    *make_immed(i)
  52. /*
  53.  *      make a node to reference an immediate value i.
  54.  */
  55. int     i;
  56. {       struct amode    *ap;
  57.         struct enode    *ep;
  58.         ep = (struct enode *)xalloc(sizeof(struct enode));
  59.         ep->nodetype = en_icon;
  60.         ep->v.i = i;
  61.         ap =(struct amode *)xalloc(sizeof(struct amode));
  62.         ap->mode = am_immed;
  63.         ap->offset = ep;
  64.         return ap;
  65. }
  66.  
  67. struct amode    *make_offset(node)
  68. /*
  69.  *      make a direct reference to a node.
  70.  */
  71. struct enode    *node;
  72. {       struct amode    *ap;
  73.         ap =(struct amode *)xalloc(sizeof(struct amode));
  74.         ap->mode = am_direct;
  75.         ap->offset = node;
  76.         return ap;
  77. }
  78.  
  79.  make_legal(ap,flags,size)
  80. /*
  81.  *      make_legal will coerce the addressing mode in ap1 into a
  82.  *      mode that is satisfactory for the flag word.
  83.  */
  84. struct amode    *ap;
  85. int             flags, size;
  86. {       struct amode    *ap2;
  87.         if( ((flags & F_VOL) == 0) || ap->tempflag )
  88.                 {
  89.                 switch( ap->mode )
  90.                         {
  91.                         case am_immed:
  92.                                 if( flags & F_IMMED )
  93.                                         return;         /* mode ok */
  94.                                 break;
  95.                         case am_areg:
  96.                                 if( flags & F_AREG )                                        return;
  97.                                 break;
  98.                         case am_dreg:
  99.                                 if( flags & F_DREG )
  100.                                         return;
  101.                                 break;
  102.                         case am_ind:    case am_indx:
  103.                         case am_indx2:  case am_xpc:
  104.                         case am_direct: case am_indx3:
  105.                                 if( flags & F_MEM )
  106.                                         return;
  107.                                 break;
  108.                         }
  109.                 }
  110.         if( flags & F_DREG )
  111.                 {
  112.                 freeop(ap);             /* maybe we can use it... */
  113.                 ap2 = (struct amode *)temp_data();      /* allocate to dreg */
  114.                 gen_code(op_move,size,ap,ap2);
  115.                 ap->mode = am_dreg;
  116.                 ap->preg = ap2->preg;
  117.                 ap->deep = ap2->deep;
  118.                 ap->tempflag = 1;
  119.                 return;
  120.                 }
  121.         if( size == 1 )
  122.                 {
  123.                 freeop(ap);
  124.                 ap2 = (struct amode *)temp_data();
  125.                 gen_code(op_move,1,ap,ap2);
  126.                 gen_code(op_ext,2,ap2,(struct amode *)0);
  127.                 freeop(ap);
  128.                 ap->mode = ap2->mode;
  129.                 ap->preg = ap2->preg;
  130.                 ap->deep = ap2->deep;
  131.                 size = 2;
  132.                 }
  133.         freeop(ap);
  134.         ap2 =(struct amode *) temp_addr();
  135.         gen_code(op_move,size,ap,ap2);
  136.         ap->mode = am_areg;
  137.         ap->preg = ap2->preg;
  138.         ap->deep = ap2->deep;
  139.         ap->tempflag = 1;
  140. }
  141.  
  142.  do_extend(ap,isize,osize,flags)
  143. /*
  144.  *      if isize is not equal to osize then the operand ap will be
  145.  *      loaded into a register (if not already) and if osize is
  146.  *      greater than isize it will be extended to match.
  147.  */
  148. struct amode    *ap;
  149. int             isize, osize, flags;
  150. {       if( isize == osize )
  151.                 return;
  152.         if( ap->mode != am_areg && ap->mode != am_dreg )
  153.                 make_legal(ap,flags & (F_AREG | F_DREG),isize);
  154.         if( ap->mode == am_areg )
  155.                 return;         /* extend is automagic */
  156.         switch( isize )
  157.                 {
  158.                 case 1:
  159.                         gen_code(op_ext,2,ap,(struct amode *)0);
  160.                 case 2:
  161.                         if( osize == 4 )
  162.                                 gen_code(op_ext,4,ap,(struct amode *)0);
  163.                 }
  164. }
  165.  
  166. int     isshort(node)
  167. /*
  168.  *      return true if the node passed can be generated as a short
  169.  *      offset.
  170.  */
  171. struct enode    *node;
  172. {       return node->nodetype == en_icon &&
  173.                 (node->v.i >= -65536 && node->v.i <= 65535);
  174. }
  175.  
  176. int     isbyte(node)
  177. /*
  178.  *      return true if the node passed can be evaluated as a byte
  179.  *      offset.
  180.  */
  181. struct enode    *node;
  182. {       return node->nodetype == en_icon &&
  183.                 (-128 <= node->v.i && node->v.i <= 127);
  184. }
  185.  
  186. struct amode    *gen_index(node)
  187. /*
  188.  *      generate code to evaluate an index node (^+) and return
  189.  *      the addressing mode of the result. This routine takes no
  190.  *      flags since it always returns either am_ind or am_indx.
  191.  */
  192. struct enode    *node;
  193. {       struct amode    *ap1, *ap2;
  194.         if( node->v.p[0]->nodetype == en_tempref &&
  195.                 node->v.p[1]->nodetype == en_tempref &&
  196.                 ( node->v.p[0]->v.i >= 8 || node->v.p[1]->v.i >= 8 ))
  197.                 {       /* both nodes are registers, one is address */
  198.                 if( node->v.p[0]->v.i < 8 )
  199.                         {
  200.                         ap1 = gen_expr(node->v.p[1],F_AREG,4);
  201.                         ap1->sreg = node->v.p[0]->v.i;
  202.                         ap1->mode = am_indx2;   /* 0(Ax,Dx) */
  203.                         ap1->offset =(struct enode *) makenode(en_icon,
  204.                                                               (struct enode *)0,
  205.                                                               (struct enode *)0);
  206.                         return ap1;
  207.                         }
  208.                 ap1 = gen_expr(node->v.p[0],F_AREG,4);
  209.                 ap2 = gen_expr(node->v.p[1],F_AREG | F_DREG,4);
  210.                 if( ap2->mode == am_dreg )
  211.                         {
  212.                         ap1->mode = am_indx2;
  213.                         ap1->sreg = ap2->preg;
  214.                         }
  215.                 else
  216.                         {
  217.                         ap1->mode = am_indx3;
  218.                         ap1->sreg = ap2->preg;
  219.                         }
  220.                 ap1->offset =(struct enode *) makenode(en_icon,
  221.                                                       (struct enode *)0,
  222.                                                       (struct enode *)0);
  223.                 return ap1;
  224.                 }
  225.         ap1 = gen_expr(node->v.p[0],F_AREG | F_IMMED,4);
  226.         if( ap1->mode == am_immed && isshort(ap1->offset) )
  227.                 {
  228.                 ap2 = gen_expr(node->v.p[1],F_AREG,4);
  229.                 ap2->mode = am_indx;
  230.                 ap2->offset = ap1->offset;
  231.                 return ap2;
  232.                 }
  233.         ap2 = gen_expr(node->v.p[1],F_ALL,4);   /* get right op */
  234.         if( ap2->mode == am_immed && isshort(ap2->offset) &&
  235.             ap1->mode == am_areg ) /* make am_indx */
  236.                 {
  237.                 ap2->mode = am_indx;
  238.                 ap2->preg = ap1->preg;
  239.                 ap2->deep = ap1->deep;
  240.                 return ap2;
  241.                 }
  242.         validate(ap1);
  243.         make_legal(ap1,F_AREG | F_VOL,4);
  244.         gen_code(op_add,4,ap2,ap1);             /* add left to address reg */
  245.         ap1->mode = am_ind;             /* make indirect */
  246.         freeop(ap2);                    /* release any temps in ap2 */
  247.         return ap1;                     /* return indirect */
  248. }
  249.  
  250. struct amode    *gen_deref(node,flags,size)
  251. /*
  252.  *      return the addressing mode of a dereferenced node.
  253.  */
  254. struct enode    *node;
  255. int             flags, size;
  256. {       struct amode    *ap1;
  257.         int             siz1;
  258.         switch( node->nodetype )        /* get load size */
  259.                 {
  260.                 case en_b_ref:
  261.                         siz1 = 1;
  262.                         break;
  263.                 case en_w_ref:
  264.                         siz1 = 2;
  265.                         break;
  266.                 case en_l_ref:
  267.                         siz1 = 4;
  268.                         break;
  269.                 }
  270.         if( node->v.p[0]->nodetype == en_add )
  271.                 {
  272.                 ap1 = gen_index(node->v.p[0]);
  273.                 do_extend(ap1,siz1,size,flags);
  274.                 make_legal(ap1,flags,size);
  275.                 return ap1;
  276.                 }
  277.         else if( node->v.p[0]->nodetype == en_autocon )
  278.                 {
  279.                 ap1 =(struct amode *) xalloc(sizeof(struct amode));
  280.                 ap1->mode = am_indx;
  281.                 ap1->preg = 6;
  282.                 ap1->offset =(struct enode *) makenode(en_icon,(struct enode *)node->v.p[0]->v.i,
  283.                                                                (struct enode *)0);
  284.                 do_extend(ap1,siz1,size,flags);
  285.                 make_legal(ap1,flags,size);
  286.                 return ap1;
  287.                 }
  288.         ap1 = gen_expr(node->v.p[0],F_AREG | F_IMMED,4); /* generate address */
  289.         if( ap1->mode == am_areg )
  290.                 {
  291.                 ap1->mode = am_ind;
  292.                 do_extend(ap1,siz1,size,flags);
  293.                 make_legal(ap1,flags,size);
  294.                 return ap1;
  295.                 }
  296.         ap1->mode = am_direct;
  297.         do_extend(ap1,siz1,size,flags);
  298.         make_legal(ap1,flags,size);
  299.         return ap1;
  300. }
  301.  
  302. struct amode    *gen_unary(node,flags,size,op)
  303. /*
  304.  *      generate code to evaluate a unary minus or complement.
  305.  */
  306. struct enode    *node;
  307. int             flags, size, op;
  308. {       struct amode    *ap;
  309.         ap = gen_expr(node->v.p[0],F_DREG | F_VOL,size);
  310.         gen_code(op,size,ap,(struct amode *)0);
  311.         make_legal(ap,flags,size);
  312.         return ap;
  313. }
  314.  
  315. struct amode    *gen_binary(node,flags,size,op)
  316. /*
  317.  *      generate code to evaluate a binary node and return
  318.  *      the addressing mode of the result.
  319.  */
  320. struct enode    *node;
  321. int             flags, size, op;
  322. {       struct amode    *ap1, *ap2;
  323.         ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG | F_AREG,size);
  324.         ap2 = gen_expr(node->v.p[1],F_ALL,size);
  325.         validate(ap1);          /* in case push occurred */
  326.         gen_code(op,size,ap2,ap1);
  327.         freeop(ap2);
  328.         make_legal(ap1,flags,size);
  329.         return ap1;
  330. }
  331.  
  332. struct amode    *gen_xbin(node,flags,size,op)
  333. /*
  334.  *      generate code to evaluate a restricted binary node and return
  335.  *      the addressing mode of the result.
  336.  */
  337. struct enode    *node;
  338. int             flags, size, op;
  339. {       struct amode    *ap1, *ap2;
  340.         ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG,size);
  341.         ap2 = gen_expr(node->v.p[1],F_DREG,size);
  342.         validate(ap1);          /* in case push occurred */
  343.         gen_code(op,size,ap2,ap1);
  344.         freeop(ap2);
  345.         make_legal(ap1,flags,size);
  346.         return ap1;
  347. }
  348. struct amode    *gen_shift(node,flags,size,op)
  349. /*
  350.  *      generate code to evaluate a shift node and return the
  351.  *      address mode of the result.
  352.  */
  353. struct enode    *node;
  354. int             flags, size, op;
  355. {       struct amode    *ap1, *ap2;
  356.         ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,size);
  357.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,1);
  358.         validate(ap1);
  359.         gen_code(op,size,ap2,ap1);
  360.         freeop(ap2);
  361.         make_legal(ap1,flags,size);
  362.         return ap1;
  363. }
  364.  
  365. struct amode    *gen_modiv(node,flags,op,modflag)
  366. /*
  367.  *      generate code to evaluate a mod operator or a divide
  368.  *      operator. these operations are done on only long
  369.  *      divisors and word dividends so that the 68000 div
  370.  *      instruction can be used.
  371.  */
  372. struct enode    *node;
  373. int             flags, op, modflag;
  374. {       struct amode    *ap1, *ap2;
  375.         if( node->v.p[0]->nodetype == en_icon )
  376.                 swap_nodes(node);
  377.         ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
  378.         ap2 = gen_expr(node->v.p[1],F_ALL,2);
  379.         validate(ap1);
  380.         gen_code(op,0,ap2,ap1);
  381.         if( modflag )
  382.                 gen_code(op_swap,0,ap1,(struct amode *)0);
  383.         gen_code(op_ext,4,ap1,(struct amode *)0);
  384.         make_legal(ap1,flags,4);
  385.         freeop(ap2);
  386.         return ap1;
  387. }
  388.  
  389.  swap_nodes(node)
  390. /*
  391.  *      exchange the two operands in a node.
  392.  */
  393. struct enode    *node;
  394. {       struct enode    *temp;
  395.         temp = node->v.p[0];
  396.         node->v.p[0] = node->v.p[1];
  397.         node->v.p[1] = temp;
  398. }
  399.  
  400. struct amode    *gen_mul(node,flags,op)
  401. /*
  402.  *      generate code to evaluate a multiply node. both operands
  403.  *      are treated as words and the result is long and is always
  404.  *      in a register so that the 68000 mul instruction can be used.
  405.  */
  406. struct enode    *node;
  407. int             flags, op;
  408. {       struct amode    *ap1, *ap2;
  409.         if( node->v.p[0]->nodetype == en_icon )
  410.                 swap_nodes(node);
  411.         ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,2);
  412.         ap2 = gen_expr(node->v.p[1],F_ALL,2);
  413.         validate(ap1);
  414.         gen_code(op,0,ap2,ap1);
  415.         freeop(ap2);
  416.         make_legal(ap1,flags,4);
  417.         return ap1;
  418. }
  419.  
  420. struct amode    *gen_hook(node,flags,size)
  421. /*
  422.  *      generate code to evaluate a condition operator node (?:)
  423.  */
  424. struct enode    *node;
  425. int             flags,size;
  426. {       struct amode    *ap1, *ap2;
  427.         int             false_label, end_label;
  428.         false_label = nextlabel++;
  429.         end_label = nextlabel++;
  430.         flags = (flags & (F_AREG | F_DREG)) | F_VOL;
  431.         falsejp(node->v.p[0],false_label);
  432.         node = node->v.p[1];
  433.         ap1 = gen_expr(node->v.p[0],flags,0);
  434.         freeop(ap1);
  435.         gen_code(op_bra,0,make_label(end_label),(struct amode *)0);
  436.         gen_label(false_label);
  437.         ap2 = gen_expr(node->v.p[1],flags,size);
  438.         if( !equal_address(ap1,ap2) )
  439.                 {
  440.                 freeop(ap2);
  441.                 if( ap1->mode == am_dreg )
  442.                         temp_data();
  443.                 else
  444.                         temp_addr();
  445.                 gen_code(op_move,size,ap2,ap1);
  446.                 }
  447.         gen_label(end_label);
  448.         return ap1;
  449. }
  450.  
  451. struct amode    *gen_asadd(node,flags,size,op)
  452. /*
  453.  *      generate a plus equal or a minus equal node.
  454.  */
  455. struct enode    *node;
  456. int             flags,size,op;
  457. {       struct amode    *ap1, *ap2;
  458.         int             ssize;
  459.         ssize = natural_size(node->v.p[0]);
  460.         if( ssize > size )
  461.                 size = ssize;
  462.         ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
  463.         ap2 = gen_expr(node->v.p[1],F_DREG | F_AREG | F_IMMED,size);
  464.         validate(ap1);
  465.         gen_code(op,ssize,ap2,ap1);
  466.         freeop(ap2);
  467.         do_extend(ap1,ssize,size,0);
  468.         make_legal(ap1,flags,size);
  469.         return ap1;
  470. }
  471.  
  472. struct amode    *gen_aslogic(node,flags,size,op)
  473. /*
  474.  *      generate a and equal or a or equal node.
  475.  */
  476. struct enode    *node;
  477. int             flags,size,op;
  478. {       struct amode    *ap1, *ap2, *ap3;
  479.         int             ssize;
  480.         ssize = natural_size(node->v.p[0]);
  481.         if( ssize > size )
  482.                 size = ssize;
  483.         ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
  484.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,size);
  485.         validate(ap1);
  486.         if( ap1->mode != am_areg )
  487.                 gen_code(op,ssize,ap2,ap1);
  488.         else
  489.                 {
  490.                 ap3 =(struct amode *) temp_data();
  491.                 gen_code(op_move,4,ap1,ap3);
  492.                 gen_code(op,size,ap2,ap3);
  493.                 gen_code(op_move,size,ap3,ap1);
  494.                 freeop(ap3);
  495.                 }
  496.         freeop(ap2);
  497.         do_extend(ap1,ssize,size,0);
  498.         make_legal(ap1,flags,size);
  499.         return ap1;
  500. }
  501.  
  502. struct amode *gen_asshift(node,flags,size,op)
  503. /*
  504.  *      generate shift equals operators.
  505.  */
  506. struct enode    *node;
  507. int             flags, size, op;
  508. {       struct amode    *ap1, *ap2, *ap3;
  509.         ap1 = gen_expr(node->v.p[0],F_ALL,size);
  510.         if( ap1->mode != am_dreg )
  511.                 {
  512.                 ap3 = (struct amode *)temp_data();
  513.                 gen_code(op_move,size,ap1,ap3);
  514.                 }
  515.         else
  516.                 ap3 = ap1;
  517.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,size);
  518.         validate(ap3);
  519.         gen_code(op,size,ap2,ap3);
  520.         freeop(ap2);
  521.         if( ap3 != ap1 )
  522.                 {
  523.                 gen_code(op_move,size,ap3,ap1);
  524.                 freeop(ap3);
  525.                 }
  526.         make_legal(ap1,flags,size);
  527.         return ap1;
  528. }
  529.  
  530. struct amode    *gen_asmul(node)
  531. /*
  532.  *      generate a *= node.
  533.  */
  534. struct enode    *node;
  535. {       struct amode    *ap1, *ap2, *ap3;
  536.         int             siz1;
  537.         siz1 = natural_size(node->v.p[0]);
  538.         ap1 = gen_expr(node->v.p[1],F_DREG | F_VOL,2);
  539.         ap2 = gen_expr(node->v.p[0],F_ALL,siz1);
  540.         if( siz1 == 1 || ap2->mode == am_areg )
  541.                 {
  542.                 ap3 = (struct amode *)temp_data();
  543.                 gen_code(op_move,siz1,ap2,ap3);
  544.                 if( siz1 == 1 )
  545.                         gen_code(op_ext,2,ap3,(struct amode *)0);
  546.                 freeop(ap3);
  547.                 }
  548.         else
  549.                 ap3 = ap2;
  550.         gen_code(op_muls,0,ap3,ap1);
  551.         gen_code(op_move,siz1,ap1,ap2);
  552.         freeop(ap2);
  553.         return ap1;
  554. }
  555.  
  556. struct amode    *gen_asmodiv(node,flags,size,op)
  557. /*
  558.  *      generate /= and %= nodes.
  559.  */
  560. struct enode    *node;
  561. int             flags, size, op;
  562. {       struct amode    *ap1, *ap2, *ap3;
  563.         int             siz1;
  564.         siz1 = natural_size(node->v.p[0]);
  565.         ap1 = (struct amode *)temp_data();
  566.         ap2 = gen_expr(node->v.p[0],F_ALL,siz1);
  567.         validate(ap1);
  568.         gen_code(op_move,siz1,ap2,ap1);
  569.         do_extend(ap1,siz1,4,0);
  570.         ap3 = gen_expr(node->v.p[1],F_ALL & ~F_AREG,2);
  571.         validate(ap2);
  572.         validate(ap1);
  573.         gen_code(op_divs,0,ap3,ap1);
  574.         freeop(ap3);
  575.         if( op != op_divs )
  576.                 gen_code(op_swap,0,ap1,(struct amode *)0);
  577.         gen_code(op_ext,4,ap1,(struct amode *)0);
  578.         gen_code(op_move,siz1,ap1,ap2);
  579.         freeop(ap2);
  580.         make_legal(ap1,flags,size);
  581.         return ap1;
  582. }
  583.  
  584. struct amode    *gen_assign(node,size)
  585. /*
  586.  *      generate code for an assignment node. if the size of the
  587.  *      assignment destination is larger than the size passed then
  588.  *      everything below this node will be evaluated with the
  589.  *      assignment size.
  590.  */
  591. struct enode    *node;
  592. int              size;
  593. {       struct amode    *ap1, *ap2;
  594.         int             ssize;
  595.         switch( node->v.p[0]->nodetype )
  596.                 {
  597.                 case en_b_ref:
  598.                         ssize = 1;
  599.                         break;
  600.                 case en_w_ref:
  601.                         ssize = 2;
  602.                         break;
  603.                 case en_l_ref:
  604.                 case en_tempref:
  605.                         ssize = 4;
  606.                         break;
  607.                 }
  608.         if( ssize > size )
  609.                 size = ssize;
  610.         ap2 = gen_expr(node->v.p[1],F_ALL,size);
  611.         ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
  612.         validate(ap2);
  613.         gen_code(op_move,ssize,ap2,ap1);
  614.         freeop(ap1);
  615.         return ap2;
  616. }
  617.  
  618. struct amode    *gen_aincdec(node,flags,size,op)
  619. /*
  620.  *      generate an auto increment or decrement node. op should be
  621.  *      either op_add (for increment) or op_sub (for decrement).
  622.  */
  623. struct enode    *node;
  624. int             flags, size, op;
  625. {       struct amode    *ap1, *ap2;
  626.         int             siz1;
  627.         siz1 = natural_size(node->v.p[0]);
  628.         if( flags & F_NOVALUE )         /* dont need result */
  629.                 {
  630.                 ap1 = gen_expr(node->v.p[0],F_ALL,siz1);
  631.                 gen_code(op,siz1,make_immed((int)node->v.p[1]),ap1);
  632.                 freeop(ap1);
  633.                 return ap1;
  634.                 }
  635.         if( flags & F_DREG )
  636.                 ap1 =(struct amode *) temp_data();
  637.         else
  638.                 ap1 =(struct amode *) temp_addr();
  639.         ap2 = gen_expr(node->v.p[0],F_ALL,siz1);
  640.         validate(ap1);
  641.         gen_code(op_move,siz1,ap2,ap1);
  642.         gen_code(op,siz1,make_immed((int)node->v.p[1]),ap2);
  643.         freeop(ap2);
  644.         do_extend(ap1,siz1,size,0);
  645.         return ap1;
  646. }
  647.  
  648.  push_param(ep)
  649. /*
  650.  *      push the operand expression onto the stack.
  651.  */
  652. struct enode    *ep;
  653. {       struct amode    *ap;
  654.         ap = gen_expr(ep,F_ALL,4);
  655.         gen_code(op_move,4,ap,push);
  656.         freeop(ap);
  657. }
  658.  
  659. int     gen_parms(plist)
  660. /*
  661.  *      push a list of parameters onto the stack and return the
  662.  *      number of parameters pushed.
  663.  */
  664. struct enode    *plist;
  665. {       int     i;
  666.         i = 0;
  667.         while( plist != 0 )
  668.                 {
  669.                 push_param(plist->v.p[0]);
  670.                 plist = plist->v.p[1];
  671.                 ++i;
  672.                 }
  673.         return i;
  674. }
  675.  
  676. struct amode    *gen_fcall(node,flags)
  677. /*
  678.  *      generate a function call node and return the address mode
  679.  *      of the result.
  680.  */
  681. struct enode    *node;
  682. int    flags;
  683. {       struct amode    *ap, *result;
  684.         int             i;
  685.         result = (struct amode *)temp_addr();
  686.         temp_addr();                    /* push any used addr temps */
  687.         freeop(result); freeop(result);
  688.         result = (struct amode *)temp_data();
  689.         temp_data(); temp_data();       /* push any used data registers */
  690.         freeop(result); freeop(result); freeop(result);
  691.         i = gen_parms(node->v.p[1]);    /* generate parameters */
  692.         if( node->v.p[0]->nodetype == en_nacon )
  693.                 gen_code(op_jsr,0,make_offset(node->v.p[0]),
  694.                         (struct amode *)0);
  695.         else
  696.                 {
  697.                 ap = gen_expr(node->v.p[0],F_AREG,4);
  698.                 ap->mode = am_ind;
  699.                 freeop(ap);
  700.                 gen_code(op_jsr,0,ap,(struct amode *)0);
  701.                 }
  702.         if( i != 0 )
  703.                 gen_code(op_add,4,make_immed(i * 4),makeareg(7));
  704.         if( flags & F_DREG )
  705.                 result =(struct amode *) temp_data();
  706.         else
  707.                 result =(struct amode *) temp_addr();
  708.         if( result->preg != 0 || (flags & F_DREG) == 0 )
  709.                 gen_code(op_move,4,makedreg(0),result);
  710.         return result;
  711. }
  712.  
  713. struct amode    *gen_expr(node,flags,size)
  714. /*
  715.  *      general expression evaluation. returns the addressing mode
  716.  *      of the result.
  717.  */
  718. struct enode    *node;
  719. int             flags, size;
  720. {       struct amode    *ap1, *ap2;
  721.         int             lab0, lab1;
  722.         int             natsize;
  723.         if( node == 0 )
  724.                 {
  725.                 printf("DIAG - null node in gen_expr.\n");
  726.                 return 0;
  727.                 }
  728.         switch( node->nodetype )
  729.                 {
  730.                 case en_icon:
  731.                 case en_labcon:
  732.                 case en_nacon:
  733.                         ap1 =(struct amode *) xalloc(sizeof(struct amode));
  734.                         ap1->mode = am_immed;
  735.                         ap1->offset = node;
  736.                         make_legal(ap1,flags,size);
  737.                         return ap1;
  738.                 case en_autocon:
  739.                         ap1 =(struct amode *) temp_addr();
  740.                         ap2 =(struct amode *) xalloc(sizeof(struct amode));
  741.                         ap2->mode = am_indx;
  742.                         ap2->preg = 6;          /* frame pointer */
  743.                         ap2->offset = node;     /* use as constant node */
  744.                         gen_code(op_lea,0,ap2,ap1);
  745.                         make_legal(ap1,flags,size);
  746.                         return ap1;             /* return reg */
  747.                 case en_b_ref:
  748.                 case en_w_ref:
  749.                 case en_l_ref:
  750.                         return gen_deref(node,flags,size);
  751.                 case en_tempref:
  752.                         ap1 =(struct amode *)xalloc(sizeof(struct amode));
  753.                         if( node->v.i < 8 )
  754.                                 {
  755.                                 ap1->mode = am_dreg;
  756.                                 ap1->preg = node->v.i;
  757.                                 }
  758.                         else
  759.                                 {
  760.                                 ap1->mode = am_areg;
  761.                                 ap1->preg = node->v.i - 8;
  762.                                 }
  763.                         ap1->tempflag = 0;      /* not a temporary */
  764.                         make_legal(ap1,flags,size);
  765.                         return ap1;
  766.                 case en_uminus:
  767.                         return gen_unary(node,flags,size,op_neg);
  768.                 case en_compl:
  769.                         return gen_unary(node,flags,size,op_not);
  770.                 case en_add:
  771.                         return gen_binary(node,flags,size,op_add);
  772.                 case en_sub:
  773.                         return gen_binary(node,flags,size,op_sub);
  774.                 case en_and:
  775.                         return gen_binary(node,flags,size,op_and);
  776.                 case en_or:
  777.                         return gen_binary(node,flags,size,op_or);
  778.                 case en_xor:
  779.                         return gen_xbin(node,flags,size,
  780. op_eor);
  781.                 case en_mul:
  782.                         return gen_mul(node,flags,op_muls);
  783.                 case en_umul:
  784.                         return gen_mul(node,flags,op_mulu);
  785.                 case en_div:
  786.                         return gen_modiv(node,flags,op_divs,0);
  787.                 case en_udiv:
  788.                         return gen_modiv(node,flags,op_divu,0);
  789.                 case en_mod:
  790.                         return gen_modiv(node,flags,op_divs,1);
  791.                 case en_umod:
  792.                         return gen_modiv(node,flags,op_divu,1);
  793.                 case en_lsh:
  794.                         return gen_shift(node,flags,size,op_asl);
  795.                 case en_rsh:
  796.                         return gen_shift(node,flags,size,op_asr);
  797.                 case en_asadd:
  798.                         return gen_asadd(node,flags,size,op_add);
  799.                 case en_assub:
  800.                         return gen_asadd(node,flags,size,op_sub);
  801.                 case en_asand:
  802.                         return gen_aslogic(node,flags,size,op_and);
  803.                 case en_asor:
  804.                         return gen_aslogic(node,flags,size,op_or);
  805.                 case en_aslsh:
  806.                         return gen_asshift(node,flags,size,op_asl);
  807.                 case en_asrsh:
  808.                         return gen_asshift(node,flags,size,op_asr);
  809.                 case en_asmul:
  810.                         return gen_asmul(node);
  811.                 case en_asdiv:
  812.                         return gen_asmodiv(node,flags,size,op_divs);
  813.                 case en_asmod:
  814.                         return gen_asmodiv(node,flags,size,op_muls);
  815.                 case en_assign:
  816.                         return gen_assign(node,size);
  817.                 case en_ainc:
  818.                         return gen_aincdec(node,flags,size,op_add);
  819.                 case en_adec:
  820.                         return gen_aincdec(node,flags,size,op_sub);
  821.                 case en_land:   case en_lor:
  822.                 case en_eq:     case en_ne:
  823.                 case en_lt:     case en_le:
  824.                 case en_gt:     case en_ge:
  825.                 case en_ult:    case en_ule:
  826.                 case en_ugt:    case en_uge:
  827.                 case en_not:
  828.                         lab0 = nextlabel++;
  829.                         lab1 = nextlabel++;
  830.                         falsejp(node,lab0);
  831.                         ap1 = (struct amode *)temp_data();
  832.                         gen_code(op_moveq,0,make_immed(1),ap1);
  833.                         gen_code(op_bra,0,make_label(lab1),(struct amode *)0);
  834.                         gen_label(lab0);
  835.                         gen_code(op_clr,4,ap1,(struct amode *)0);
  836.                         gen_label(lab1);
  837.                         return ap1;
  838.                 case en_cond:
  839.                         return gen_hook(node,flags,size);
  840.                 case en_void:
  841.                         natsize = natural_size(node->v.p[0]);
  842.                         freeop(gen_expr(node->v.p[0],F_ALL | F_NOVALUE,natsize))
  843. ;
  844.                         return gen_expr(node->v.p[1],flags,size);
  845.                 case en_fcall:
  846.                         return gen_fcall(node,flags);
  847.                 default:
  848.                         printf("DIAG - uncoded node in gen_expr.\n");
  849.                         return 0;
  850.                 }
  851. }
  852.  
  853. int     natural_size(node)
  854. /*
  855.  *      return the natural evaluation size of a node.
  856.  */
  857. struct enode    *node;
  858. {       int     siz0, siz1;
  859.         if( node == 0 )
  860.                 return 0;
  861.         switch( node->nodetype )
  862.                 {
  863.                 case en_icon:
  864.                         if( -128 <= node->v.i && node->v.i <= 127 )
  865.                                 return 1;
  866.                         if( -32768 <= node->v.i && node->v.i <= 32767 )
  867.                                 return 2;
  868.                         return 4;
  869.                 case en_fcall:  case en_labcon:
  870.                 case en_nacon:  case en_autocon:
  871.                 case en_l_ref:  case en_tempref:
  872.                 case en_cbl:    case en_cwl:
  873.                         return 4;
  874.                 case en_b_ref:
  875.                         return 1;
  876.                 case en_cbw:
  877.                 case en_w_ref:
  878.                         return 2;
  879.                 case en_not:    case en_compl:
  880.                 case en_uminus: case en_assign:
  881.                 case en_ainc:   case en_adec:
  882.                         return natural_size(node->v.p[0]);
  883.                 case en_add:    case en_sub:
  884.                 case en_mul:    case en_div:
  885.                 case en_mod:    case en_and:
  886.                 case en_or:     case en_xor:
  887.                 case en_lsh:    case en_rsh:
  888.                 case en_eq:     case en_ne:
  889.                 case en_lt:     case en_le:
  890.                 case en_gt:     case en_ge:
  891.                 case en_land:   case en_lor:
  892.                 case en_asadd:  case en_assub:
  893.                 case en_asmul:  case en_asdiv:
  894.                 case en_asmod:  case en_asand:
  895.                 case en_asor:   case en_aslsh:
  896.                 case en_asrsh:
  897.                         siz0 = natural_size(node->v.p[0]);
  898.                         siz1 = natural_size(node->v.p[1]);
  899.                         if( siz1 > siz0 )
  900.                                 return siz1;
  901.                         else
  902.                                 return siz0;
  903.                 case en_void:   case en_cond:
  904.                         return natural_size(node->v.p[1]);
  905.                 default:
  906.                         printf("DIAG - natural size error.\n");
  907.                         break;
  908.                 }
  909.         return 0;
  910. }
  911.  
  912.  gen_compare(node)
  913. /*
  914.  *      generate code to do a comparison of the two operands of
  915.  *      node.
  916.  */
  917. struct enode    *node;
  918. {       struct amode    *ap1, *ap2;
  919.         int             size;
  920.         size = natural_size(node);
  921.         ap1 = gen_expr(node->v.p[0],F_AREG | F_DREG, size);
  922.         ap2 = gen_expr(node->v.p[1],F_ALL,size);
  923.         validate(ap1);
  924.         gen_code(op_cmp,size,ap2,ap1);
  925.         freeop(ap2);
  926.         freeop(ap1);
  927. }
  928.  
  929.  truejp(node,label)
  930. /*
  931.  *      generate a jump to label if the node passed evaluates to
  932.  *      a true condition.
  933.  */
  934. struct enode    *node;
  935. int             label;
  936. {       struct amode    *ap1;
  937.         int             siz1;
  938.         int             lab0;
  939.         if( node == 0 )
  940.                 return;
  941.         switch( node->nodetype )
  942.                 {
  943.                 case en_eq:
  944.                         gen_compare(node);
  945.                         gen_code(op_beq,0,make_label(label),(struct amode *)0);
  946.                         break;
  947.                 case en_ne:
  948.                         gen_compare(node);
  949.                         gen_code(op_bne,0,make_label(label),(struct amode *)0);
  950.                         break;
  951.                 case en_lt:
  952.                         gen_compare(node);
  953.                         gen_code(op_blt,0,make_label(label),(struct amode *)0);
  954.                         break;
  955.                 case en_le:
  956.                         gen_compare(node);
  957.                         gen_code(op_ble,0,make_label(label),(struct amode *)0);
  958.                         break;
  959.                 case en_gt:
  960.                         gen_compare(node);
  961.                         gen_code(op_bgt,0,make_label(label),(struct amode *)0);
  962.                         break;
  963.                 case en_ge:
  964.                         gen_compare(node);
  965.                         gen_code(op_bge,0,make_label(label),(struct amode *)0);
  966.                         break;
  967.                 case en_ult:
  968.                         gen_compare(node);
  969.                         gen_code(op_blo,0,make_label(label),(struct amode *)0);
  970.                         break;
  971.                 case en_ule:
  972.                         gen_compare(node);
  973.                         gen_code(op_bls,0,make_label(label),(struct amode *)0);
  974.                         break;
  975.                 case en_ugt:
  976.                         gen_compare(node);
  977.                         gen_code(op_bhi,0,make_label(label),(struct amode *)0);
  978.                         break;
  979.                 case en_uge:
  980.                         gen_compare(node);
  981.                         gen_code(op_bhs,0,make_label(label),(struct amode *)0);
  982.                         break;
  983.                 case en_land:
  984.                         lab0 = nextlabel++;
  985.                         falsejp(node->v.p[0],lab0);
  986.                         truejp(node->v.p[1],label);
  987.                         gen_label(lab0);
  988.                         break;
  989.                 case en_lor:
  990.                         truejp(node->v.p[0],label);
  991.                         truejp(node->v.p[1],label);
  992.                         break;
  993.                 case en_not:
  994.                         falsejp(node->v.p[0],label);
  995.                         break;
  996.                 default:
  997.                         siz1 = natural_size(node);
  998.                         ap1 = gen_expr(node,F_ALL,siz1);
  999.                         gen_code(op_tst,siz1,ap1,(struct amode *)0);
  1000.                         freeop(ap1);
  1001.                         gen_code(op_bne,0,make_label(label),(struct amode *)0);
  1002.                         break;
  1003.                 }
  1004. }
  1005.  
  1006.  falsejp(node,label)
  1007. /*
  1008.  *      generate code to execute a jump to label if the expression
  1009.  *      passed is false.
  1010.  */
  1011. struct enode    *node;
  1012. int             label;
  1013. {       struct amode    *ap;
  1014.         int             siz1;
  1015.         int             lab0;
  1016.         if( node == 0 )
  1017.                 return;
  1018.         switch( node->nodetype )
  1019.                 {
  1020.                 case en_eq:
  1021.                         gen_compare(node);
  1022.                         gen_code(op_bne,0,make_label(label),(struct amode *)0);
  1023.                         break;
  1024.                 case en_ne:
  1025.                         gen_compare(node);
  1026.                         gen_code(op_beq,0,make_label(label),(struct amode *)0);
  1027.                         break;
  1028.                 case en_lt:
  1029.                         gen_compare(node);
  1030.                         gen_code(op_bge,0,make_label(label),(struct amode *)0);
  1031.                         break;
  1032.                 case en_le:
  1033.                         gen_compare(node);
  1034.                         gen_code(op_bgt,0,make_label(label),(struct amode *)0);
  1035.                         break;
  1036.                 case en_gt:
  1037.                         gen_compare(node);
  1038.                         gen_code(op_ble,0,make_label(label),(struct amode *)0);
  1039.                         break;
  1040.                 case en_ge:
  1041.                         gen_compare(node);
  1042.                         gen_code(op_blt,0,make_label(label),(struct amode *)0);
  1043.                         break;
  1044.                 case en_ult:
  1045.                         gen_compare(node);
  1046.                         gen_code(op_bhs,0,make_label(label),(struct amode *)0);
  1047.                         break;
  1048.                 case en_ule:
  1049.                         gen_compare(node);
  1050.                         gen_code(op_bhi,0,make_label(label),(struct amode *)0);
  1051.                         break;
  1052.                 case en_ugt:
  1053.                         gen_compare(node);
  1054.                         gen_code(op_bls,0,make_label(label),(struct amode *)0);
  1055.                         break;
  1056.                 case en_uge:
  1057.                         gen_compare(node);
  1058.                         gen_code(op_blo,0,make_label(label),(struct amode *)0);
  1059.                         break;
  1060.                 case en_land:
  1061.                         falsejp(node->v.p[0],label);
  1062.                         falsejp(node->v.p[1],label);
  1063.                         break;
  1064.                 case en_lor:
  1065.                         lab0 = nextlabel++;
  1066.                         truejp(node->v.p[0],lab0);
  1067.                         falsejp(node->v.p[1],label);
  1068.                         gen_label(lab0);
  1069.                         break;
  1070.                 case en_not:
  1071.                         truejp(node->v.p[0],label);
  1072.                         break;
  1073.                 default:
  1074.                         siz1 = natural_size(node);
  1075.                         ap = gen_expr(node,F_ALL,siz1);
  1076.                         gen_code(op_tst,siz1,ap,(struct amode *)0);
  1077.                         freeop(ap);
  1078.                         gen_code(op_beq,0,make_label(label),(struct amode *)0);
  1079.                         break;
  1080.                 }
  1081. }
  1082.  
  1083.  
  1084.